"""
    TorrentBrowser plugin for XBMC
    Copyright (C) 2011-2012 Markus Langenoja
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    Function [TBScrape]
    -------------------
    * scrapeInfo(item) - Tries to download information from TheMovieDB API
      for the input item.
    * getIMDBID(title) - Tries to fetch IMDB-ID from a stripped movie title
    * scrapeTMDB(item) - Parsing the XML format produced by TheMovieDB API
      and filling the item with information.
"""
import string, re, sys
from datetime import datetime
import time
import TBTools

class TBScraper( TBTools.TBTools ):
    __deb__ = sys.modules[ "__main__" ].__deb__
    __plugin__ = sys.modules[ "__main__" ].__plugin__
    __web__ = sys.modules[ "__main__" ].__web__
    __settings__ = sys.modules[ "__main__" ].__settings__

    TMDBAPI = 'http://www.omdbapi.com/?i=tt'
    IMDBAPI = 'http://www.omdbapi.com/?t='

    def scrapeInfo( self, item ):
        get = item.get
        
        # Save the original title which enables the choice to show relase name or title
        originaltitle = get( 'title' )

        # Check if IMDB-id is given else find it
        if get( 'imdb' ) != None:
            if self.__deb__:
                print self.__plugin__ + '::DEBUG::TBScrape::' + 'scrapeInfo:: IMDB-ID Given: tt%s' % (get( 'imdb' ))
            # If IMDB-id exists
            query = self.TMDBAPI + get( 'imdb' )
        else:
            if self.__deb__:
                print self.__plugin__ + '::DEBUG::TBScrape::' + 'scrapeInfo:: IMDB-ID NOT Given, Fetching'
              
            # If not, clean up title from scraped info and fetch imdb-ID  
            title = self.replaceBadSigns( get( 'title' ) )
            # Here the release name is stripped!
            cleanedtitle = self.cleanString( title )
            strippedtitle = self.stripTitle( cleanedtitle )
            
            if self.__deb__:
                print strippedtitle

            item['imdb'] = self.getIMDBID( strippedtitle )

            # Build TheMovieDB API query with parsed iMDB-ID
            if get( 'imdb' ):
                if self.__deb__:
                    print self.__plugin__ + '::DEBUG::TBScrape::' + 'scrapeInfo:: Fetched IMDB-ID: tt%s' % (get( 'imdb' ))
                query = self.TMDBAPI + get( 'imdb' )
            else:
                if self.__deb__:
                    print self.__plugin__ + '::DEBUG::TBScrape::' + 'scrapeInfo:: Failed to retrieve IMDB-ID'
                query = False
                

        # If a valid query is return from statements above, get page and
        # scrape info into infoList
        check = ''
        if query:
            if self.__deb__:
                print self.__plugin__ + '::DEBUG::TBScrape::' + 'scrapeInfo:: query for TMDB %s ' % (query)
            item['tmdbdata'] = self.__web__.webOpen( query )
            # Add the title before scraping TheMovieDB to verify that data has been scraped
            check = item['title']   
            try:
                item = self.scrapeTMDB( item )
            except:
                if self.__deb__:
                    print self.__plugin__ + '::DEBUG::TBScrape::' + 'scrapeInfo:: Could not scrape using query %s' % (query)
                pass
            
        # If the settings are set to show the releasename instead of title.
        if self.__settings__.getSetting( 'original' ) == 'true':
            item['title'] = originaltitle
        # Else check if the title is unchanged after scraping (probably caused by failure)
        elif check == item['title']:
            if type( title ) == tuple:
                item['title'] = title[0]
            else:
                item['title'] = title
            
        # Why is this done?
        self.item = item
        
        if self.__deb__:
            print self.__plugin__ + '::DEBUG::TBScrape::' + 'scrapeInfo:: Finished scraping item'
            
        return self.item

    def getIMDBID( self, data ):
        if self.__deb__:
            try:
                print self.__plugin__ + '::DEBUG::TBScrape::' + 'getIMDBID:: Fetching IMDB-ID using %s ' % (data)
            except:
                print self.__plugin__ + '::DEBUG::TBScrape::' + 'getIMDBID:: Fetching IMDB-ID using %s ' % (data[0])
        # Searches the iMDB-API using Title.

        # Create the query, searches with year if given.
        if type( data ) == tuple:
            info = string.replace( data[0], ' ', '%20' ) + '&y=' + data[1]
            title = data[0]
        else:
            info = string.replace( data, ' ', '%20' )
            title = data
        query = self.IMDBAPI + info
        
        try:
            page = self.__web__.webOpen( query )
        except: 
            self.showOK('Error','IMDB-API isn\'nt responding')
            return
        
        if re.match( '\{"Response":".*', page ):
            # If bad response, give no imdbid back.
            if self.__deb__:
                print self.__plugin__ + '::DEBUG::TBScrape::' + 'getIMDBID:: Parse Error, Nothing found. %s' % (title)
            imdbid = None
        else:
            # Else start by splitting the title from both the input AND the title obtained
            # using the iMDB-API and sort the words by size, starting with the longest
            # Also strips the API-title since it can contain characters stripped when
            # cleaning title.
            compInput = sorted( title.split(), key=len, reverse=True )
            apiTitle = re.compile( '"Title":"(.+?)"' ).findall( page )[0]
            apiTitle = self.stripTitle( apiTitle )
            compAPI = sorted( apiTitle.split(), key=len, reverse=True )

            if self.__deb__:
                print self.__plugin__ + '::DEBUG::TBScrape::' + 'getIMDBID:: Comparing %s with %s' % (compInput,compAPI)

            try:
                # Comparisson between title and title from iMDB-API.
                # Only returns a true hit if the two longest word in the title matches.
                # Crashes if title concist of only one word.
                if compInput[0].lower() == compAPI[0].lower():
                    # Compares the longest word in the titles
                    if compInput[1].lower() == compAPI[1].lower():
                        # Compares the second longest word in titles.
                        ok = True
                    else:
                        if self.__deb__:
                            print self.__plugin__ + '::DEBUG::TBScrape::' + 'getIMDBID:: %s =/= %s' % (compInput[1],compAPI[1])
                        ok = False
                else:
                    if self.__deb__:
                        print self.__plugin__ + '::DEBUG::TBScrape::' + 'getIMDBID:: %s =/= %s' % (compInput[0],compAPI[0])
                    ok = False
            except:
                # If list is just one entry, compare this and return ok if all good.
                if compInput[0].lower() == compAPI[0].lower():
                    ok = True
                else:
                    if self.__deb__:
                        print self.__plugin__ + '::DEBUG::TBScrape::' + 'getIMDBID:: %s =/= %s' % (compInput[0],compAPI[0])
                    ok = False

            # If the comparissons above return an ok = True, then fetch imdbid finally.       
            if ok:
                imdbid = re.compile( '"imdbID":"tt(.+?)"' ).findall( page )[0]
                if self.__deb__:
                    print self.__plugin__ + '::DEBUG::TBScrape::' + 'getIMDBID:: Match Successful for ID: tt%s' % (str( imdbid ))
            else:
                imdbid = None
            
        return imdbid

    def scrapeTMDB( self, item ):
        get = item.get
        page = get( 'tmdbdata' )
        item.pop( 'tmdbdata' )

        if self.__deb__:
            print self.__plugin__ + '::DEBUG::TBScrape::' + 'scrapeTMDB:: Running scrapeTMDB for %s ' % (get( 'title' ))
        # Initiate info dictionary

        # Extract wanted information from TheMovieDB, if it doesn't exist it doesn't write anything to the dictionary.
        try:
            item['title'] = self.replaceBadSigns( re.compile( '"Title":"(.+?)"' ).findall( page )[0] )
        except: pass
        try:
            item['plot'] = self.replaceBadSigns( re.compile( '"Plot":"(.+?)"' ).findall( page )[0] )
        except: pass
        try:
            runtimeHoursPart = re.compile( '"Runtime":"(\d+) h.*?"' ).findall( page )
            runtimeMinutesPart = re.compile( '"Runtime":".*?(\d+) min"' ).findall( page )
            
            runtimeInMinutes = 0
                        
            if runtimeHoursPart:
                runtimeInMinutes = runtimeInMinutes + int(runtimeHoursPart[0])*60
                
            if runtimeMinutesPart:
                runtimeInMinutes = runtimeInMinutes + int(runtimeMinutesPart[0])                        
                
            item['duration'] = runtimeInMinutes
        except: pass
        try:
            item['mpaa'] = re.compile( '"Rated":"(.+?)"' ).findall( page )[0]
        except: pass
        try:
            item['rating'] = float( re.compile( '"imdbRating":"(.+?)"' ).findall( page )[0] )
        except: pass
        try:
            genre = re.compile( '"Genre":"(.+?)"' ).findall( page )
            item['genre'] = string.join( genre, '/' )
        except: pass
        try:
            item['poster'] = re.compile( '"Poster":"(.+?)"' ).findall( page )[0]
        except: pass
        try:
            item['backdrop'] = re.compile( '"Poster":"(.+?)"' ).findall( page )[0]
        except: pass
        try:
            dateString = re.compile( '"Released":"(.+?)"' ).findall( page )[0]
            dateObject = None
            try:
                dateObject = datetime.strptime(dateString, '%d %b %Y')
            except TypeError:
                dateObject = datetime.fromtimestamp(time.mktime(time.strptime(dateString, '%d %b %Y')))        
            item['premiered'] = dateObject.strftime("%d.%m.%Y")
            item['aired'] = dateObject.strftime("%d.%m.%Y")
        except: pass        
        try:
            item['year'] = re.compile( '"Year":"(.+?)"' ).findall( page )[0]
        except: pass        
        try:
            item['director'] = re.compile( '"Director":"(.+?)"' ).findall( page )[0]
        except: pass
        try:
            item['writer'] = re.compile( '"Writer":"(.+?)"' ).findall( page )[0]
        except: pass        
        try:
            item['cast'] = re.compile( '"Actors":"(.+?)"' ).findall( page )[0].split(',')
        except: pass
        try:
            item['votes'] = re.compile( '"imdbVotes":"(.+?)"' ).findall( page )[0]
        except: pass        

        # Return list
        return item
